package com.niiwoo.civet.account.service.local.bill;

import com.niiwoo.civet.account.dao.entity.NiiwooBillPlatform;
import com.niiwoo.civet.account.dao.entity.NiiwooBillPlatformExample;
import com.niiwoo.civet.account.dao.entity.NiiwooBillPlatformExampleExt;
import com.niiwoo.civet.account.dao.mapper.NiiwooBillPlatformMapper;
import com.niiwoo.civet.account.dao.mapper.NiiwooBillPlatformMapperExt;
import com.niiwoo.civet.account.dto.bill.BillBase;
import com.niiwoo.civet.account.dto.request.PlatformBillQueryRequest;
import com.niiwoo.civet.account.enums.BillDateReleatedTypeEnum;
import com.niiwoo.civet.account.enums.BillSecondSubjectEnum;
import com.niiwoo.civet.account.enums.BillStatusEnum;
import com.niiwoo.civet.account.enums.OrderTypeEnum;
import com.niiwoo.tripod.service.component.SnowflakeIdWorker;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.time.FastDateFormat;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;

import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Objects;


/**
 * 平台账单Service
 *
 * @author xiaoyingping
 * @create 2017-11-20 10:06
 **/
@Service
@Slf4j
public class NiiwooBillPlateformService {

    @Autowired
    private NiiwooBillPlatformMapper niiwooBillPlatformMapper;
    @Autowired
    private NiiwooBillPlatformMapperExt niiwooBillPlatformMapperExt;
    @Autowired
    private BillDateReleatedService billDateReleatedService;
    @Autowired
    private SnowflakeIdWorker snowflakeIdWorker;


    /**
     * 新增平台账单
     *
     * @param niiwooBillPlatform
     * @return
     */
    public int addNiiwooBillPlatform(BillBase billBase, NiiwooBillPlatform niiwooBillPlatform) {
        niiwooBillPlatform.setBillId(snowflakeIdWorker.nextId());
        niiwooBillPlatform.setBillBaseId(billBase.getId());
        niiwooBillPlatform.setAccountId(billBase.getAccountId());
        niiwooBillPlatform.setInvestId(billBase.getInvestId());
        niiwooBillPlatform.setGuaranteeId(billBase.getGuaranteeId());
        niiwooBillPlatform.setOrderId(billBase.getOrderId());
        niiwooBillPlatform.setOrderType(billBase.getOrderType());
        niiwooBillPlatform.setStatus(billBase.getStatus());
        niiwooBillPlatform.setCreateTime(billBase.getCreateTime());
        niiwooBillPlatform.setUpdateTime(billBase.getUpdateTime());

        DateTime createTime = new DateTime(niiwooBillPlatform.getCreateTime());
        niiwooBillPlatform.setYearMonth(createTime.toString("yyyyMM"));
        niiwooBillPlatform.setYearMonthDay(createTime.toString("yyyy-MM-dd"));

        BillSecondSubjectEnum secondSubjectEnum = BillSecondSubjectEnum.getEnumByCode(niiwooBillPlatform.getSecondSortCode());
        niiwooBillPlatform.setFirstSortCode(secondSubjectEnum.getFirstSubject().getCode());
        niiwooBillPlatform.setInoutType(secondSubjectEnum.getFirstSubject().getInOutType());
        niiwooBillPlatform.setTitle(secondSubjectEnum.getCodeName());

        billDateReleatedService.addBillDateReleated(niiwooBillPlatform);
        return niiwooBillPlatformMapper.insertSelective(niiwooBillPlatform);
    }

    /**
     * 修改账单状态：通过订单ID
     *
     * @param orderId
     * @param statusEnum
     */
    public int updateBillStatusByOrderId(String orderId, OrderTypeEnum orderType, BillStatusEnum statusEnum) {
        List<String> yearMonthDay = billDateReleatedService.queryBillDates(BillDateReleatedTypeEnum.ORDER_ID, orderId);

        NiiwooBillPlatformExample example = new NiiwooBillPlatformExample();
        NiiwooBillPlatformExample.Criteria criteria = example.createCriteria();
        criteria.andOrderIdEqualTo(orderId);
        criteria.andOrderTypeEqualTo(orderType.getCode());
        if(!CollectionUtils.isEmpty(yearMonthDay)){
            criteria.andYearMonthDayIn(yearMonthDay);
        }else{
            log.error("{}找不到对应的billDate", yearMonthDay);
        }

        NiiwooBillPlatform niiwooBillPlatform = new NiiwooBillPlatform();
        niiwooBillPlatform.setStatus(statusEnum.getValue());
        niiwooBillPlatform.setUpdateTime(new Date());
        return niiwooBillPlatformMapper.updateByExampleSelective(niiwooBillPlatform, example);
    }

    /**
     * 查询账单列表：通过订单ID和订单类型
     * @param orderId
     * @param orderType
     * @return
     */
    public List<NiiwooBillPlatform> getByOrderIdAndType(String orderId, OrderTypeEnum orderType){
        Assert.hasLength(orderId, "orderId不能为空");
        Assert.notNull(orderType, "orderType不能为空");

        List<String> yearMonthDay = billDateReleatedService.queryBillDates(BillDateReleatedTypeEnum.ORDER_ID, orderId);

        NiiwooBillPlatformExample example = new NiiwooBillPlatformExample();
        NiiwooBillPlatformExample.Criteria criteria = example.createCriteria();
        criteria.andOrderIdEqualTo(orderId);
        criteria.andOrderTypeEqualTo(orderType.getCode());
        if(!CollectionUtils.isEmpty(yearMonthDay)){
            criteria.andYearMonthDayIn(yearMonthDay);
        }else{
            log.error("{}找不到对应的billDate", yearMonthDay);
        }

        return niiwooBillPlatformMapper.selectByExample(example);
    }



    /**
     * 【分页】查询用户账单列表
     *
     * @param billQueryRequest
     * @return
     */
    public List<NiiwooBillPlatform> pagePlatformBills(PlatformBillQueryRequest billQueryRequest) {
        NiiwooBillPlatformExampleExt example = generatePlatformBillExample(billQueryRequest);
        if (null == example) {
            return Collections.EMPTY_LIST;
        }

        //分页条件
        Integer offset = billQueryRequest.getOffset();
        Integer pageSize = billQueryRequest.getPageSize();
        Assert.notNull(offset, "offset不能为空");
        Assert.notNull(pageSize, "pageSize不能为0");
        example.setOffset(offset);
        example.setPageSize(pageSize);
        example.setOrderByClause("create_time desc");

        return niiwooBillPlatformMapperExt.pageByExample(example);
    }

    /**
     * 统计账单数量
     *
     * @param billQueryRequest
     * @return
     */
    public Long countPlatformBills(PlatformBillQueryRequest billQueryRequest) {
        NiiwooBillPlatformExample example = generatePlatformBillExample(billQueryRequest);
        if (null == example) {
            return 0L;
        }

        return niiwooBillPlatformMapper.countByExample(example);
    }


    /**
     * 通过baseId获取平台账单列表
     * @param billBaseId
     * @param createTime 创建时间
     * @return
     */
    public List<NiiwooBillPlatform> getCheckAccountBillsByBaseId(Long billBaseId, Date createTime) {
        Assert.notNull(createTime, "createTime不能为空");

        NiiwooBillPlatformExample niiwooBillPlatformExample = new NiiwooBillPlatformExample();
        NiiwooBillPlatformExample.Criteria criteria = niiwooBillPlatformExample.createCriteria();
        criteria.andBillBaseIdEqualTo(billBaseId);
        criteria.andYearMonthDayEqualTo(new DateTime(createTime).toString("yyyy-MM-dd"));
        return niiwooBillPlatformMapper.selectByExample(niiwooBillPlatformExample);
    }


    private NiiwooBillPlatformExampleExt generatePlatformBillExample(PlatformBillQueryRequest billQueryRequest) {
        Assert.notNull(billQueryRequest, "billQueryRequest不能为空");
        NiiwooBillPlatformExampleExt example = new NiiwooBillPlatformExampleExt();
        NiiwooBillPlatformExampleExt.Criteria criteria = example.createCriteria();

        boolean haveSharding = false;
        Date startCreateDate = billQueryRequest.getStartCreateDate();
        Date endCreateDate = billQueryRequest.getEndCreateDate();
        if(Objects.nonNull(startCreateDate) && Objects.nonNull(endCreateDate)){
            haveSharding = true;

            String startYearMonthDay = FastDateFormat.getInstance("yyyy-MM-dd").format(startCreateDate);
            String endYearMonthDay = FastDateFormat.getInstance("yyyy-MM-dd").format(endCreateDate);
            criteria.andYearMonthDayBetween(startYearMonthDay, endYearMonthDay);
            criteria.andCreateTimeBetween(startCreateDate, endCreateDate);
        }

        if(Objects.nonNull(billQueryRequest.getProjectId())){
            criteria.andProjectIdEqualTo(billQueryRequest.getProjectId());

            List<String> billDateList = billDateReleatedService.queryBillDates(BillDateReleatedTypeEnum.PROJECT_ID, String.valueOf(billQueryRequest.getProjectId()));
            if(!CollectionUtils.isEmpty(billDateList)){
                criteria.andYearMonthDayIn(billDateList);
                haveSharding = true;
            }
        }
        if (Objects.nonNull(billQueryRequest.getBillId())) {
            criteria.andBillIdEqualTo(billQueryRequest.getBillId());
        }
        if (Objects.nonNull(billQueryRequest.getAccountId())) {
            criteria.andAccountIdEqualTo(billQueryRequest.getAccountId());
        }
        if (Objects.nonNull(billQueryRequest.getRelationUserId())) {
            criteria.andRelationUserIdEqualTo(billQueryRequest.getRelationUserId());
        }
        if (Objects.nonNull(billQueryRequest.getInoutType())) {
            criteria.andInoutTypeEqualTo(billQueryRequest.getInoutType().getType());
        }

        if (Objects.nonNull(billQueryRequest.getFirstSortCode())) {
            criteria.andFirstSortCodeEqualTo(billQueryRequest.getFirstSortCode());
        }
        if (Objects.nonNull(billQueryRequest.getSecondSortCode())) {
            criteria.andSecondSortCodeEqualTo(billQueryRequest.getSecondSortCode());
        }
        if (Objects.nonNull(billQueryRequest.getProjectType())) {
            criteria.andProjectTypeEqualTo(billQueryRequest.getProjectType());
        }
        if (Objects.nonNull(billQueryRequest.getChannelCode())) {
            criteria.andChannelCodeEqualTo(billQueryRequest.getChannelCode());
        }

        if(haveSharding){
            return example;
        }
        return null;
    }

    public List<NiiwooBillPlatform> listByBaseId(Long billBaseId, String yearMonthDay){
        NiiwooBillPlatformExample example = new NiiwooBillPlatformExample();
        NiiwooBillPlatformExample.Criteria criteria = example.createCriteria();
        criteria.andBillBaseIdEqualTo(billBaseId);
        criteria.andYearMonthDayEqualTo(yearMonthDay);
        return niiwooBillPlatformMapper.selectByExample(example);
    }

}
